setClass("FCMNonParamClusterAlg",contains="VNonParamClusterAlg",
		representation(
				.method="character"
		),
		prototype=prototype(
				.description="FCM based non parametric Clustering algorithm class",
				.method="FCM"
		
		)
)   

#helper functions
calcNoisePerc <- function(fcmClustReslutObject){
	defuzzifiedClusters <- vegclust::defuzzify(fcmClustReslutObject)$memb
	if("N" %in% colnames(defuzzifiedClusters)){
		percentOfNoisePoints <- sum(defuzzifiedClusters[,"N"])/dim(defuzzifiedClusters)[1]
	}else{
		percentOfNoisePoints <-0.0
	}
	
	return(percentOfNoisePoints)
}

#methods
#initialization method 
setMethod("initialize",
		signature="FCMNonParamClusterAlg",
		function(.Object,indexObject,method="FCM",...){
			.Object <-callNextMethod(.Object,indexObject,...)
			.Object@.method <- method
			
			
			return(.Object)
		})


setMethod("clusterize",
		signature="FCMNonParamClusterAlg",
		definition=function(.Object,inputSet,...){
			callNextMethod(.Object,inputSet,...)
			
			
			#make parameter grid
			#mParams <- seq(from=1.5,to=3.0,length.out=3)#TODO change it in final version
			mParams <- seq(from=2,to=2,length.out=1)
			gri <-expand.grid(genClusNumSeq(inputSet),mParams)
			
			
						
			#set clust function
			clustFun <- NULL
			
			if(.Object@.method == "NC" || .Object@.method=="GKN"){
				clustFun <- clusterWithNoise
			}
			if(.Object@.method == "FCM" || .Object@.method=="GK"){
				clustFun <- clusterize
			}
			
			#initial best cluster
			bestScore <- -.Machine$double.xmax
			bestClustering <- numeric(0)
			clustSeq <- genClusNumSeq(inputSet)
			
			#find best cluster
			clustList <- foreach(i =seq(1,nrow(gri),1))%dopar%{
			#clustList <- lapply(1:nrow(gri),FUN=function(i){
			#for(i in 1:nrow(gri)){
				#new clusterizator object
				print("Init clusterizer")
				clustObject <- new("FCMParamClusterAlg", clusterNum = gri[i,]$Var1, m = gri[i,]$Var2,
							method = .Object@.method)
				
				#print(paste("clustStart:",i,sep=" "))
				#find clusters
				#print(paste("inputSetX dims:",dim(inputSet$X)[2]))
				clusters <- clustFun(clustObject,inputSet)
				#print("SCORE")
				#score clusters
				clusters2score <-numeric(0)
				scoreSetX <- matrix()
				if(.Object@.method == "NC" || .Object@.method=="GKN"){
					#do not score noise points
					#find noise cluster number
					nClustNum <- max(unique(clusters))
					#remove noise points
					clusters2score <- clusters[clusters!=nClustNum]
					scoreSetX <-inputSet$X[(clusters>0),,drop=FALSE]
					
				}
				else{
					clusters2score <- clusters
					scoreSetX <- inputSet$X
					
				}
				print(paste("FClust: ",.Object@.method));#print(clusters)
				if(length(clusters2score) >0){
					score <- ScoreSet(.Object@.indexObject,list(X=scoreSetX),clusters2score)
				}
				else{
					score <- -.Machine$double.xmax
				}
				
				if(is.na(score) || is.infinite(score)){score <- -.Machine$double.xmax}
				
				list(Score=score,Clusters=clusters)
#				if(score > bestScore){
#					bestScore <- score
#					bestClustering <- clusters
#				}
				
			}
			#)
			for( i in 1:length(clustList)){
				if(clustList[[i]]$Score > bestScore){
					bestScore <- clustList[[i]]$Score
					bestClustering <-clustList[[i]]$Clusters
				}
			}
			
			
			
			
			
			return(bestClustering)
		}
) 
setMethod("get_description",
		signature="FCMNonParamClusterAlg",
		definition=function(.Object){
			paste(.Object@.description,":",.Object@.method,sep=" ")
		})
